package com.scs.application.core.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.model.TreeEntity;
import com.scs.application.core.utils.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * 树形service，增强普通service
 *
 */
public class TreeServiceImpl<M extends BaseMapper<T>, T extends TreeEntity> extends BaseServiceImpl<M, T> implements ITreeService<T> {

    protected void preSave(T entity) {

        Long sort = entity.getSort() == null ? 10 : entity.getSort();


        T parent = null;
        if (entity.getParentId() == null || (parent = getById(entity.getParentId())) == null) {
            entity.setParentId("0");
            entity.setParentIds(",0,");
        } else {
            entity.setParentId(parent.getId());
            entity.setParentIds(parent.getParentIds() + parent.getId() + ",");
        }
        entity.setSort(sort);

        if (StringUtils.isNotBlank(entity.getId()) && entity.getId().equals(entity.getParentId())) {
            throw new BusinessException("保存失败，不允许将父级节点修改为自身节点");
        }

        if (parent != null) {
            // 例如：软件有下属分类  MSCM，此时将软件的父级分类设为 MSCM。应该阻止这种情况
            // id   parent_id   name    parent_ids
            // 1    0           软件    ,0,
            // 2    1           MSCM    ,0,1,
            // 允许调换后的结果
            // 1    2           软件    ,0,1,2,
            // 2    1           MSCM    ,0,1
            if (entity.getParentIds().contains("," + entity.getId() + ",")) {
                throw new BusinessException("保存失败，不允许将父级节点修改为其下级节点（包含所有下级节点）");
            }
        }
    }

    @Override
    public boolean saveCascadeById(T entity) {
        preSave(entity);
        return super.save(entity);
    }

    @Override
    public boolean updateCascadeById(T entity) {
        String oldParentIds = entity.getParentIds();


        preSave(entity);

        // 之前的子级节点
        List<T> children = this.baseMapper.selectList(new QueryWrapper<T>().like("parent_ids", oldParentIds + entity.getId() + ","));

        // 更新子节点的 parent_ids
        for (T child : children) {
            child.setParentIds(child.getParentIds().replace(oldParentIds, entity.getParentIds()));
            super.updateById(child);
        }
        return super.updateById(entity);
    }

    @Override
    public boolean removeCascadeById(Serializable id) {
        // 删除子级节点
        super.remove(new QueryWrapper<T>().like("parent_ids", "," + id + ","));

        return super.removeById(id);
    }

    @Override
    public boolean removeCascadeBatchByIds(Collection<? extends Serializable> idList) {

        if (CollectionUtils.isEmpty(idList)) {
            return false;
        }

        QueryWrapper<T> entityWrapper = new QueryWrapper();
        for (Serializable id : idList) {
            // 删除子级节点
            super.remove(entityWrapper.like("parent_ids", "," + id + ","));
        }
        return super.removeByIds(idList);
    }


}

